package com.scs.application.modules.msg.sender;

import com.scs.application.core.exception.BusinessException;
import com.scs.application.core.utils.StringUtils;
import com.scs.application.modules.msg.enums.HandlerType;
import com.scs.application.modules.msg.enums.MessageType;
import com.scs.application.modules.msg.handler.MessageSenderHandler;
import com.scs.application.modules.msg.model.Message;
import com.google.common.collect.Lists;
import org.springframework.beans.factory.annotation.Autowired;

import java.util.List;

/**
 */
public abstract class MessageSender<T extends Message> {
    private List<MessageSenderHandler> messageSenderHandlers;

    @Autowired(required = false)
    public void setMessageSenderHandlers(List<MessageSenderHandler> messageSenderHandlers) {
        this.messageSenderHandlers = messageSenderHandlers;
    }

    protected void beforeSend(T msg) {
        MessageType messageType = msg.getMessageType();
        if (StringUtils.isBlank(msg.getTplKey())) {
            if (StringUtils.isBlank(msg.getTitle())) {
                throw new BusinessException(messageType.getDesc() + "发送失败：标题不能为空");
            }

            if (StringUtils.isBlank(msg.getContent())) {
                throw new BusinessException(messageType.getDesc() + "发送失败：内容不能为空");
            }
        }
    }

    /**
     * 实际发送短信方法
     * @param msg   要发送的消息
     */
    protected abstract void doSend(T msg);


    public final void send(T msg) {
        List<MessageSenderHandler> messageSenderHandlers = this.messageSenderHandlers;
        if (messageSenderHandlers == null) {
            messageSenderHandlers = Lists.newArrayList();
        }
        Exception ex = null;

        MessageSenderContext senderContext = MessageSenderContext.getOrNew();
        try {
            senderContext.begin();
            beforeSend(msg);
            doSend(msg);
        } catch (Exception e) {
            ex = e;
            messageSenderHandlers.stream().filter(o -> HandlerType.ERROR.equals(o.getHandlerType()))
                    .forEach(o -> o.handle(msg, e));
        } finally {
            Exception finalEx = ex;
            messageSenderHandlers.stream().filter(o -> HandlerType.COMPLETE.equals(o.getHandlerType()))
                    .forEach(o -> o.handle(msg, finalEx));

            MessageSenderContext.clear();
        }
    }


}
